home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / stuffky.exe / STUFFKB3.ASM < prev   
Encoding:
Assembly Source File  |  1991-07-17  |  24.1 KB  |  572 lines

  1. COMMENT         |
  2. STUFFKB3.ASM   By Richard Kanarek-      Compuserve ID 72371,111
  3.                                         GENIE Address: R.KANAREK
  4. Overview:
  5.         +Description of file.
  6.         +Notes on the Keyboard Buffer.
  7.         +Sample Assembly Language program which stuffs the phrase
  8.          "BUY BONDS" into your keyboard buffer. May be easily adapted
  9.          for use with Turbo C (tm- Borland Int. Inc.) by changing
  10.          a few lines (all of which are marked).
  11.         +Sample Turbo C program which calls the assembler routine
  12.          and uses it to stuff "RLK" into the buffer.
  13.  
  14. +Description of file.
  15. ---------------------
  16. This file contains information on the operation of the keyboard
  17. buffer in IBM & Zenith personal computers as well as sample procedure
  18. (in Assembler) that can be called from a Turbo C (tm) program. This
  19. file was intended to be compiled using TASM but since only TASM's
  20. MASM mode is used, compilation using Microsoft's (tm) assembler
  21. should not be difficult.
  22.  
  23. Unlike most programs, whose purpose is only to be executed, the
  24. purpose of this program is to explain the operation of the Keyboard
  25. buffer. This file is meant to help those who might wish to "stuff"
  26. or otherwise modify the keyboard buffer  on any IBM computer. Some
  27. reasons why you might want to fiddle with the keyboard buffer:
  28. - Call another program while exiting an already running program
  29. without tying up ANY memory or interfering with the running program
  30. in any way.
  31. - Change the keyboard buffer size to allow more or fewer keystrokes
  32. to be stored.
  33. - Write a TSR that can demonstrate other programs by simulating keystrokes,
  34.  without having or needing access to the other programs source code.
  35.  
  36. Things to consider:
  37. - EXTENSIVELY TEST ANY PROGRAM THAT STUFFS THE KEYBOARD BUFFER!!! Very slight
  38.   mistakes can create impressively buggy software! Make sure that the routines
  39.   do not leave any lasting effects (i.e. try running other programs after
  40.   running any program that stuffs the buffer). Assume that any software
  41.   that will stuff the keyboard will crash on your first effort writing it-
  42.   IN HEAVEN'S NAME SAVE TO FLOPPY DISK (THEN REMOVE THE DISK FROM YOUR DRIVE)
  43.   YOUR WORK IN PROGRESS BEFORE TRYING YOU NEW PROGRAM! HARD DISK USERS- DEBUG
  44.   AT YOUR OWN RISK! The memory area near the key board buffer is used for
  45.   important purposes by your computer. Accidentally writing to them will cause
  46.   the computer to operate unreliably- though not necessarily so unreliably
  47.   that you will notice it immediately! For example: while developing the
  48.   routines below, there was a bug present which would cause the procedure
  49.   to (apparently) not write to the buffer but it did not seem to cause any
  50.   other problems (TASM, TLINK, & Turbo C still worked fine). When I tried
  51.   starting Turbo Debugger, my computer would lock up! Once again: Test, Test,
  52.   Test!!!  
  53.  
  54. - These routines have only been tried on Heath/Zenith XT similar
  55.   computer (not 100% clone, but close). Verify on you own if the
  56.   concepts described below will work else where!
  57.  
  58. - If you are sure that your computers BIOS supports int 16h fun 05h you can
  59.   use it to safely write data to the keyboard buffer:
  60.   Calling Registers:    (From "System BIOS for IBM PC/XT/AT Computers &
  61.         ax=05h                  Compatibles", Phoenix Tech. Reference)
  62.         ch=scan code
  63.         cl=ascii character
  64.   Return Registers:
  65.         al= 00h=No Error, 01h= Buffer Full.
  66.   This BIOS int. is only supported on latter xt and on at computers. To
  67.   determine if the computer running a program supports INT 16h fun.'s 5h,10h,
  68.   12h...
  69.   (quoting Phoenix book...)
  70.   a) Use Fun. 05h to write FFFFh to the keyboard buffer. If AL returns 00h
  71.     then fun. 05h is supported.
  72.   b) Read the keyboard using fun. 10 as many times as there are words in
  73.     the keyboard buffer (the book recommends 15). If FFFFh is returned fun.
  74.     10h-12h are supported.
  75. - This program was NOT extensively tested. USE AT YOUR OWN RISK! Please
  76.   report any problems or useful information on keyboard stuffing to the
  77.   author so that I may keep these notes as complete as possible.
  78. - Note: IBM AT & PS/2 Keyboards generate different codes than do the XT
  79.   keyboards this program was written for. I don't believe that these
  80.   differences will affect this program in any way but this has not been
  81.   tested yet. You may wish to check that different keyboards work equally
  82.   well before using these routines in any important programs.
  83. - Note: This program was compiled (using Turbo Assembler & TLINK) with
  84.   case sensitivity & all debugging options on. Recompiling should not produce
  85.   any error messages.
  86. - IMPORTANT: Needless to say (but that won't stop me!)...
  87. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  88. +The information and routines below may be used without charge so long as    +
  89. +the author is not held, in any way, labial for the soundness of the routines+
  90. +or accuracy of the information. Any source code included in this file may   +
  91. +be considered "Public Domain".                              RLK Jan 9 1990  +
  92. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  93.  
  94.  
  95. +Notes on the Keyboard Buffer.
  96. ------------------------------
  97. The keyboard buffer is a circular buffer.
  98. The main components of the keyboard buffer are: 
  99. 1) A variable which keeps track of where the scan code for the oldest (first)
  100. unread key is located. This variable is often called the Head.
  101. 2) A variable which keeps track of where the scan code for the most recently 
  102. press key is located. This variable is often called the Tail.
  103. 3) A variable which contains the offset for the beginning of the keyboard
  104. buffer's memory area. This variable is often called the Start.
  105. 4) A variable which contains the offset for the end of the keyboard
  106. buffer's memory area. This variable is often called the End.
  107.  
  108. As keys are pressed, the scan code (WORD) is placed in a memory location
  109. pointed to by Tail. The tail pointer is then incremented by two (2 bytes=
  110. one word) unless the Tail pointer is 2 memory locations (bytes) before 
  111. the Head pointer in which case the keyboard buffer is now full.
  112. If incrementing the Tail pointer makes it greater than the value of End,
  113. Tail is set to equal Start.
  114. When a BIOS interrupt reads a scan code from the keyboard buffer, it reads
  115. the scan code pointed to by Head & then increments the Head pointer by
  116. two. (Note: No key is read from the buffer if the buffer is empty, i.e.
  117. if Head=Tail.)
  118. If incrementing the Head pointer makes it greater than the value of End,
  119. Head is set to equal Start.
  120.  
  121.  
  122. ==IBM========================================================================
  123.  (Heath/ZDS computer programmers, see next section).
  124. Note Worthy BIOS/RAM Locations concerning the Keyboard Buffer:
  125.  Note Segment = 040h
  126. Offset Data type       Description
  127. 80h    Word            Address of the start of the keyboard buffer, i.e.
  128.                        40h:[40h:80h] = the location of the first word of
  129.                        the keyboard buffer.
  130. 82h    Word            Address of the end of the keyboard buffer.
  131.  
  132. 1Eh-2Eh --------       16 bytes of the default keyboard buffer area.
  133.                        Note: By changing the start and end addresses
  134.                        of the keyboard buffer (while making sure that
  135.                        the RAM you point the buffer to isn't being/going
  136.                        to be used by anything else!) you can greatly
  137.                        increase/decrease the buffer size. (For example,the
  138.                        reference manual for my Heath Zenith 148 computer has
  139.                        a small program in it which changes the buffer to 4000 bytes.)
  140.  
  141. 1Ah    Word            Pointer to the first word to be read from the
  142.                        keyboard buffer- called "Head" by expert keyboard
  143.                        stuffers like you and I! Note: since the keyboard
  144.                        buffer is circular in nature, the first word of the
  145.                        keyboard buffer is not necessarily the first word
  146.                        to be read (but the word pointed to by this offset
  147.                        IS!).
  148.  
  149. 1Ch    Word            Pointer to the end of the buffer (NOT to be confused
  150.                        with the end of the buffer AREA!) where the next
  151.                        keypress scan code is to be written- expert keyboard
  152.                        stuffers like you and I call it the "Tail".
  153.  
  154. ==Zenith=====================================================================
  155. Zenith Computer keyboard buffers are arranged in a manor very similar to
  156.  IBM computers except as follows:
  157. Address    Data type   Description
  158. F000:00C8  Word        Segment Address of Keyboard Buffer area.
  159. F000:00CA  Word        Offset address of Start of keyboard buffer- i.e.
  160.                        keyboard buffer mem. starts @ [F000:00C8]:[F000:00CA]
  161. F000:00CC  Word        Offset address of End of keyboard buffer- i.e.
  162.                        keyboard buffer memory Ends at [F000:00C8]:[F000:00CC]
  163. Notice that Zenith BIOS makes changing the size of the keyboard buffer very
  164. easy- just point [F000:00C8]:[F000:00CA] to the start of an unused area of
  165. memory and [F000:00C8]:[F000:00CC] to the end of the block of memory.
  166. By default, Zenith keyboard buffers occupy the same memory area as IBM
  167. computers.
  168.  
  169. ==GENERAL====================================================================
  170.  
  171. Note: Each buffer WORD contains:
  172.  LSB=ASCII Value of key (zero if function key)
  173.  MSB= Scan Code
  174.  Where: [WORD]=[MSB][LSB]
  175.                  ^    ^
  176.                Byte  Byte
  177. KEEP IN MIND THAT WORDS ARE STORED IN MEMORY WITH THE LEAST SIGNIFICANT BYTE
  178.  FIRST AND THE MOST SIGNIFICANT BYTE LAST, SO A SCAN CODE IS STORED
  179.  IN MEMORY IN A MANOR OPPOSITE TO THAT WHICH WAS JUST DESCRIBED.
  180.  
  181. Useful (?) Observations on the operation of the keyboard buffer:
  182.        (Observations made on a Heath Zenith 148 [xt- `99%' compatible]
  183.         computer.)
  184. - When keyboard buffer is empty head=tail.
  185. - Cntrl/Alt/Break Clears buffer (sets head=tail).
  186. - Buffer holds 15 Key presses (default) max.
  187. - Buffer "start" & "end" addresses are inclusive.
  188. - Buffer full: tail= head-2 (Remember: buffer is circular- if head-2 would
  189.                                be less than start, wrap around buffer)
  190.  
  191. Note: The below examples assume that the keyboard buffer has been setup
  192. in the way that a IBM computer would by default. It has been left up to
  193. you to determine, if necessary, whether this default condition still exists.
  194.  
  195.  Bibliography:
  196.  Technical Reference manual for Heath/Zenith 148 Computer.
  197.  "System BIOS for IBM PC/XT/AT Computers& Compatibles" by Pheniox Technologies
  198.  
  199. +Sample Assembly Language program:
  200. ----------------------------------
  201.  
  202. ---Actual Sample Program Starts Below.
  203.  
  204. ;As supplied, the code below will clear the keyboard buffer & then stuff the
  205. ; keyboard with a sample phrase. To perform a truly useful task, you will have
  206. ; to include the below routines is another program. If you wish, you may 
  207. ; easily adapt this file for linking with Turbo C (tm) by simply making
  208. ; the changes that are clearly noted. If linked with TC you will be
  209. ; able to stuff the keyboard buffer with any phrase that will fit into
  210. ; the buffer so long as the phrase uses only characters supported in
  211. ; the table below. You are, of course, free to change the routine in
  212. ; any way or use it as a model to create a similar routine in a language
  213. ; of your choice.
  214.                 |
  215.  
  216. ;Change Model & language as required.
  217. .model small,C
  218. ;by setting language to "C" TASM (tm) will automatically insert underbars 
  219. ; under all extrn & public references (darn helpful, don't you think?).
  220.  
  221. locals  ;Permits temporary lables that start with @@
  222.  
  223. %OUT Compiling STUFFKB3.ASM by Richard Kanarek. Version 1.10
  224.  
  225. start   equ     80h         ;Location of Buffer Start offset.
  226. endd    equ     82h         ;Location of Buffer End offset.
  227. head    equ     1Ah         ;Location of first unread keypress.
  228. tail    equ     1Ch         ;Location of last unread keypress.
  229.  
  230. .stack  ;default 1k
  231. ;Note: Eliminate .stack statement if linking routine with Turbo C. Turbo C
  232. ; (like other languages) will declare a stack area.
  233.  
  234.  
  235. .data
  236. table label BYTE    ;The table (below) contains a list of SCAN CODES
  237.         ; which are used with the ASCII codes contained in the ASCIIZ
  238.         ; (0h terminated string) keyboard stuffing string to stuff
  239.         ; the keyboard buffer.
  240.         ;Note: the layout of this array is somewhat difficult to explain or
  241.         ; understand however it is key to the operation of the below procedure.
  242.         ; Please read the following carefully and/or repeatedly.
  243.         ;All entries in the keyboard buffer consist of two bytes (one word).
  244.         ;When viewed as a word, the first byte is the key code - a number
  245.         ; indicating which key was pressed & the second byte indicates the 
  246.         ; ASCII code for the key press (0 for function keys). KEEP IN MIND
  247.         ; THAT WORDS ARE STORED IN MEMORY WITH THE LEAST SIGNIFICANT BYTE
  248.         ; FIRST AND THE MOST SIGNIFICANT BYTE LAST, SO A SCAN CODE IS STORED
  249.         ; IN MEMORY IN A MANOR OPPOSITE TO THAT WHICH WAS JUST DESCRIBED.
  250.         ;table_ascii_start is an Equate (#define) which is assigned the
  251.         ; ascii value of the first key code contained in the array `table'.
  252.         ;The array `table' is actually made up exclusively of key codes. The
  253.         ; first key code in the array `table' has the ASCII code of
  254.         ; table_ascii_start. The second key code in the array `table' has the
  255.         ; ASCII code of table_ascii_start + 1.
  256.         ;Note: This table does not support all ascii keys (life is to short
  257.         ; to enter 255 entries into the table). You many feel free to add
  258.         ; entries if you like.
  259.         ;Note: Keys not supported are given the value FFh if their ASCII
  260.         ; code is between table_ascii_start & (table_ascii_start + table_size)
  261.         ; The only significance of the value FFh is that I decided to assign
  262.         ; it to keys I did not enter into the table and that I wrote the below
  263.         ; procedure to check for it.
  264.         ; Other unsupported keys are just ignored in the table (though the
  265.         ; routine below checks if a character in the string to be stuffed
  266.         ; is actually included in the table).
  267.         ;Note: Table entries must be in sequence, from lowest ASCII code to
  268.         ; highest ASCII code.
  269. table_ascii_start = 0Dh ;ASCII code for the first (lowest) keyboard key
  270.                         ; covered by this table (i.e. the following key).
  271.         db 1Ch  ;[Return]  <-- ASCII code = table_ascii_start
  272.  
  273.         db 12h dup (0FFh)       ;I don't think it would be a useful use of
  274.                                 ; my time to fill in [Cntrl]/[keypress] codes,
  275.                                 ; do you?
  276.  
  277.         db 39h  ;[Space]
  278.  
  279.         db 0Ah dup (0FFh)       ;       <ditto>
  280.  
  281.         db 33h  ;,
  282.         db 0Ch  ;-
  283.         db 34h  ;.
  284.         db 35h  ;/
  285.  
  286.         db 02h  ;0
  287.         db 03h  ;1
  288.         db 04h  ;2
  289.         db 05h  ;3
  290.         db 06h  ;4
  291.         db 07h  ;5
  292.         db 08h  ;6
  293.         db 09h  ;7
  294.         db 0Ah  ;8
  295.         db 0Bh  ;9
  296.  
  297.         db 27h  ;:
  298.         db 27h  ;;
  299.         db 33h  ;<
  300.         db 0Dh  ;=
  301.         db 34h  ;>
  302.         db 35h  ;?
  303.  
  304.         db 03h  ;@
  305.  
  306.         db 1Eh  ;A      Notice that I only entered capital letters into
  307.         db 30h  ;B              the table. Don't call the procedure
  308.         db 2Eh  ;C              with a ASCIIZ string containing lower case
  309.         db 20h  ;D              letters unless you enter them in the table.
  310.         db 12h  ;E
  311.         db 21h  ;F
  312.         db 22h  ;G
  313.         db 23h  ;H
  314.         db 17h  ;I
  315.         db 24h  ;J
  316.         db 25h  ;K
  317.         db 26h  ;L
  318.         db 32h  ;M
  319.         db 31h  ;N
  320.         db 18h  ;O
  321.         db 19h  ;P
  322.         db 10h  ;Q
  323.         db 13h  ;R
  324.         db 1Fh  ;S
  325.         db 14h  ;T
  326.         db 16h  ;U
  327.         db 2Fh  ;V
  328.         db 11h  ;W
  329.         db 2Dh  ;X
  330.         db 15h  ;Y
  331.         db 2Ch  ;Z
  332.  
  333.         db 1Ah  ;[
  334.         db 2Bh  ;\
  335.         ;End of table.
  336.         table_size=$-table      ;stores size of table in equate table_size.
  337.  
  338. test_string     db      "BUY BONDS",0   ;for test only.
  339. ;Note: Remove test string if "main:" is removed, i.e. when calling the
  340. ; below routine from another program.
  341. ;Note: The above string does not contain an ASCII character 0Dh. The effect
  342. ; is therefore the same as your pressing the [B], [U], [Y], [Space], etc.
  343. ; keys without pressing the enter key! Adding a ODh value would be the
  344. ; same as pressing the enter key.
  345.  
  346.  
  347. .code
  348.  
  349. ;Note: Eliminate "main:" code as required.
  350. ;\/ \/ \/ \/ \/ \/ \/ \/ \/
  351.  
  352. main:   ;used for test only.
  353.  
  354.         mov ax,@data    ;Initialize Data Segment.
  355.         mov ds,ax       ;
  356.  
  357.         mov ax,OFFSET [test_string]     ;Note: Don't forget to include a ascii
  358.                                 ; char. 13d (return) in the string (if needed).
  359.         push ax         ;Offset (pointer) to test String is pointed to by
  360.                         ; word pushed on stack (even when the routine is called
  361.                         ; by another program).
  362.  
  363.         call stuffkybd  ;This is the routine that "Stuffs" the keyboard.
  364.  
  365.         pop bx          ;Remove the pushed pointer from the stack.
  366.  
  367.         ;return to DOS.
  368.         mov ah,4ch  ;sets ah reg for dos interrupt 21h
  369.         int 21h     ; function 4ch (Terminate)
  370.  
  371. ;/\ /\ /\ /\ /\ /\ /\ /\ /\
  372.  
  373.  
  374. proc stuffkybd
  375.  
  376. ;Include the following line in the calling Turbo C program:
  377. ;extern int stuffkybd(char *asciiz_string)
  378. ;Note: string must be upper case only and use only those characters supported
  379. ; by the table (above).
  380.  
  381. ;stuffkybd returns 1 if stuffkybd fails, 0 otherwise.
  382.  
  383. ;Notice (by examining the table, above) that only CAPITAL letters, numbers,
  384. ; and a few other keys are currently supported. If you wish to use an
  385. ; unsupported key, you must add its scan code to the proper position in the
  386. ; table.
  387.  
  388. ;Note: In order to work a)DS must point to the segment containing the ASCIIZ
  389. ; string to stuff & b) a word offset pointer, such that DS:OFFSET = Start
  390. ; of ASCIIZ must have been pushed on to the stack before calling this
  391. ; procedure.
  392.  
  393.         public stuffkybd
  394.         arg string:WORD
  395.  
  396.         push es ;Saves some registers. You may need to save other registers
  397.         push si ; or flags depending upon the calling program!
  398.         push di ;
  399.  
  400.         mov ax,40h      ;Initializes es register to
  401.         mov es,ax       ; BIOS RAM segment.
  402.  
  403.         
  404.         
  405.         ;make keyboard buffer appear full so that no (alphanumeric) keypresses
  406.         ; will interfere with loading.
  407.                 mov ax,WORD ptr [es:start]      ;Load AX with the start
  408.                                                 ; offset address (seg.=40h)
  409.                                                 ; of the keyboard buffer.
  410.  
  411.                 cli     ;Disables interrupts (prevents any more writes
  412.                         ; to the keyboard buffer).
  413.  
  414.                 mov WORD ptr [es:head],ax       ;Head now equals Start.
  415.  
  416.                 mov ax,WORD ptr [es:endd]
  417.                 dec ax  ;AX - 1 (same as Head-2 since Head now = Start).
  418.                 mov WORD ptr [es:tail],ax       ;Buffer now looks full.
  419.  
  420.                 sti     ;Permits interrupts.
  421.  
  422.  
  423.         ;fill buffer...
  424.  
  425.         ;First, prepare registers:
  426.         mov bx,OFFSET table     ;used by xlat
  427.         mov si,[string]         ;si-used to point to string 
  428.                                 ; memory locations (offsets)
  429.         mov di,WORD ptr [es:head]       ;DI- used to point to keyboard buffer
  430.                                         ; locations.
  431.  
  432.         ;Second, prepare loop:
  433.         mov cx,WORD ptr [es:endd]       ;TASM is actually quite smart enough
  434.                                ; to figure out that [es:endd] is pointing to
  435.                                ; a WORD- I just like to make sure that we
  436.                                ; are both (TASM & I) understanding each other.
  437.         sub cx,WORD ptr [es:start]
  438.                 ;cx now contains the max. number of BYTEs to stuff.
  439.         shr cx,1        ;divide by 2
  440.                 ;cx now contains the max. number of WORDS to stuff.
  441.  
  442.         @@looptop2:
  443.         mov al,BYTE ptr [DS:si]         ;loads al with ascii char
  444.                                         ; from string.
  445.         cmp al,0        ;Is ascii value =0 (i.e. is char. string terminator)?
  446.         jne @@continue_loop2
  447.         jmp SHORT @@stuffkybd_success
  448.  
  449.     @@continue_loop2:
  450.  
  451.         mov ah,al       ;save ascii char. value.
  452.  
  453.         sub al,table_ascii_start        ;Adj. ascii value for use with XLAT.
  454.  
  455.         jl @@stuffkybd_fail     ;if the ascii value is less than those the
  456.                                 ; table is setup for, then jump.
  457.  
  458.         cmp al,table_size       ;Check that the ascii value is not greater
  459.                                 ; than those the table was setup for.
  460.         jg @@stuffkybd_fail
  461.  
  462.         xlat    ;Shazame! al now contains the scan code for the ascii key.
  463.  
  464.         ;Was the value returned in al by xlat a real value or one of those
  465.         ; phoney FFh's I entered into the table because I was to lazy to
  466.         ; enter all possible values?
  467.  
  468.         cmp al,0FFh
  469.         je @@stuffkybd_fail
  470.  
  471.         xchg al,ah      ;puts the word value in the correct order.
  472.  
  473.         mov WORD ptr [es:di],ax ;`stuff' keyboard buffer
  474.  
  475.         inc di  ;Point di to next WORD in keyboard buffer.
  476.         inc di  ; (two inc's = fast `add di,2')
  477.         inc si  ;Point si to next BYTE in keyboard stuff string.
  478.  
  479.         loop @@looptop2 ;Dec CX then jump to @@looptop2 if cx<>0.
  480.  
  481.     @@loop2exit:
  482.         ;If PC reaches this point:
  483.         ; a) The null terminator for the string has not been reached yet.
  484.         ;       and
  485.         ; b) The string is bigger than the buffer.
  486.         ;       or
  487.         ; b) The string size = the max size of the buffer.
  488.         ;Lets find out which.
  489.  
  490.         mov ax,WORD ptr [es:si]
  491.         cmp ax,0
  492.         je @@stuffkybd_success
  493.  
  494. @@stuffkybd_fail:
  495.         mov ax,WORD ptr [es:head]       ;
  496.         mov WORD ptr [es:tail],ax       ;"clears" keyboard buffer.
  497.         mov ax,1        ;stuffkybd returns 1 if stuffkybd fails, 0 otherwise.
  498.         jmp SHORT @@return2caller
  499. @@stuffkybd_success:
  500.         mov ax,WORD ptr [es:endd]       ;Calculate new value for `tail'.
  501.         sal cx,1
  502.         sub ax,cx
  503.         mov WORD ptr [es:tail],ax       ;Load new value into tail.
  504.         xor ax,ax       ;returns 0
  505. @@return2caller:
  506.  
  507. @@pop_n_ret:
  508.         pop di
  509.         pop si
  510.         pop es
  511.         ret
  512.  
  513. stuffkybd endp
  514.  
  515.  
  516. end main
  517. ;Note: Change to just `end' if eliminating "main:" section (i.e. if
  518. ; calling from another program.
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526. ;A sample Turbo C 2.01 (tm- Borland Int. Inc.) program appears below. Use
  527. ; your favorite text editor to extract & compile it, if you wish.
  528.  
  529.  
  530.  
  531. COMMENT |
  532. A sample Turbo C program you can use after you've made the few changes
  533. (to this program) noted.
  534.  
  535.  
  536. /*
  537. Example on calling stuffkybd. For complete notes see STUFFKYBD?.ASM
  538.  
  539.         Richard Kanarek   Compuserve 72371,111  GENIE R.KANAREK
  540. */
  541.  
  542.  
  543. #include <stdio.h>
  544. #include <conio.h>
  545.  
  546.         extern int stuffkybd(char * teststring); /* returns 0 if ok, 1 if
  547.                                                         fail. */
  548.  
  549. main()
  550. {
  551.         char *teststring="RLK";
  552.                 /*Note: 1) Turbo C automatically adds the
  553.                 0 string terminator. 2) RLK is just printed at the DOS
  554.                 prompt (when SAMPLE.EXE is run from DOS). If you replace
  555.                 RLK with a command you will have to add a 0Dh character
  556.                 (for a CR- \x0d).
  557.                 Idea: You might wish to change STUFFKB?.ASM so that
  558.                 rather than just stuffing the string into the keyboard
  559.                 it also fills the remaining space with spaces (20h). This
  560.                 would prevent the user from appending any keystrokes to
  561.                 the text you loaded into the buffer. */
  562.  
  563.         int a;
  564.  
  565.         clrscr();       /*Clears the monitor screen. */
  566.         a=stuffkybd(teststring);
  567.         printf("Return code: %d \n",a);
  568. }
  569.  
  570.         |
  571.  
  572.